<template>
	<view class="wanl-chat">
		<view class="edgeInsetTop"></view>
		<view @touchstart="hideDrawer">
			<scroll-view class="cu-chat" scroll-y="true" :scroll-with-animation="scrollAnimation"
				:scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory"
				upper-threshold="50">
				<!-- 加载历史数据waitingUI -->
				<view class="loading" v-show="isHistoryLoading">
					<view class="spinner">
						<view class="rect1"></view>
						<view class="rect2"></view>
						<view class="rect3"></view>
						<view class="rect4"></view>
						<view class="rect5"></view>
					</view>
				</view>
				<view v-for="(row, index) in msgList" :key="index" :id="'msg' + row.id">

					<view class="cu-item self" v-if="row.identity == 'my'">
						<view class="main" v-if="row.message.type == 'text'">
							<view class="content bg-green">
								<rich-text :nodes="row.message.content"></rich-text>
							</view>
						</view>
						<view class="cu-avatar radius" :style="{ backgroundImage: 'url(' +row.from_info.avatar + ')' }">
						</view>
						<view class="date">{{row.create_time}}</view>
					</view>

					<view class="cu-item" v-else>
						<view class="cu-avatar radius"
							:style="{ backgroundImage: 'url(' + row.from_info.avatar + ')' }">
						</view>
						<view class="main" v-if="row.message.type == 'text'">
							<view class="content">
								<rich-text :nodes="row.message.content"></rich-text>
							</view>
						</view>
						<view class="date ">{{ row.create_time }}</view>
					</view>

				</view>
				<view id='bottom'></view>
			</scroll-view>
		</view>
		<!-- 抽屉栏 -->
		<view class="popup-layer" :class="{showLayer: popupLayerClass}" @touchmove.stop.prevent="discard">
			<!-- 表情 -->
			<view :class="{ hidden: hideEmoji }">
				<view class="emoji">
					<scroll-view class="emojinav" scroll-x scroll-with-animation>
						<view class="item">
							<view :class="item == TabCur ? 'emojibg' : ''" v-for="(item, index) in emojiList.categories"
								:key="index" @tap="tabSelect" :data-id="item"
								:style="{ backgroundImage: 'url(' + emojiList.groups[item][0].url + ')' }"></view>
						</view>
					</scroll-view>
					<!-- 列表 -->
					<scroll-view v-for="(emoji, groups) in emojiList.groups" :key="groups" v-if="TabCur == groups"
						class="subject" scroll-y scroll-with-animation>
						<view class="item grid margin-bottom text-center col-5">
							<view v-for="(item, index) in emoji" :key="index" @tap="addEmoji(item.value)"
								:style="{ backgroundImage: 'url(' + item.url + ')' }"></view>
						</view>
					</scroll-view>
				</view>
			</view>
			<!-- 更多功能 1.0.2升级 -->
			<view class="solid-top" :class="{ hidden: hideMore }">
				<view class="opmenu solid-top">
					<!-- #ifndef H5 -->
					<view class="box" @tap="camera">
						<view class="icon wanl-gray"><text class="wlIcon-31paishexuanzhong"></text></view>
						<text class="text-sm">拍摄</text>
					</view>
					<!-- #endif -->
					<view class="box" @tap="chooseImage">
						<view class="icon wanl-gray"><text class="wlIcon-tupian1"></text></view>
						<text class="text-sm">照片</text>
					</view>
				</view>
			</view>
		</view>
		<!-- 底部输入栏 -->
		<view class="input-box" v-if="youInfo.is_show!=0"  :class="{ emptybottom: emptybottom, showLayer: popupLayerClass}"
			@touchmove.stop.prevent="discard">
			<view class="w20"></view>
			<view class="textbox">
				<view class="text-mode">
					<view class="box">
						<textarea auto-height="true" maxlength="300" :show-confirm-bar="false" cursor-spacing="90"
							v-model="textMsg" @focus="textareaFocus" @blur="textareaBlur" @confirm="sendText" />
					</view>
					<view class="em" @tap="chooseEmoji">
						<view class="wlIcon-biaoqing2"></view>
					</view>
				</view>
			</view>
			<view class="send" @tap="sendText">
				<text class="wlIcon-zhifeiji" v-if="textMsg"></text>
				<text class="wlIcon-fasong" v-else></text>
			</view>
		</view>
		<!-- 提示 1.0.2升级 -->
	</view>
</template>
<script>
	const emotions = require('./json/emotions.json');
	import {
		mapMutations
	} from 'vuex';
	export default {
		data() {
			return {
				to_id: 0,
				textMsg: '', //文字消息
				isHistoryLoading: false, //消息列表
				reload: false,
				scrollAnimation: false,

				msgImgList: [],
				// 取消底部
				emptybottom: false,

				isVoice: false,

				// 抽屉参数
				popupLayerClass: false,
				// more参数
				hideMore: true,
				//表情定义
				//表情
				TabCur: '默认',
				hideEmoji: true,
				emojiList: this.emojiData(),
				// Sysmodel: this.$wanlshop.wanlsys().model

				scrollTop: 0,
				scrollToView: '',

				$params: '',
				youInfo: '',
				current_page: 1,
				msgList: [],
			};
		},
		onLoad(option) {
			this.to_id = option.to_id
			this.$params = option
			this.getInfo()
			this.loadHistory(0)
			// 监听服务消息
			uni.$off('$onChat', this.onSend);
			uni.$on('$onChat', this.onSend);
		},
		// 监听返回
		onUnload() {
			uni.$off('$onChat', this.onSend);
		},
		onShow() {
			this.scrollTop = 9999999;
		},
		methods: {
			getInfo() {
				this.$request('/master/message/userInfo', this.$params).then(res => {
					this.youInfo = res.data
					uni.setNavigationBarTitle({
						title: res.data?.name || '聊天'
					})
				})
			},
			loadHistory(e) {
				if (this.isHistoryLoading) return
				// 说明加载过一次，并且没有任何记录了
				if (this.reload) return
				this.isHistoryLoading = true; //参数作为进入请求标识，防止重复请求
				this.scrollAnimation = false; //关闭滑动动画
				let view_id = this.msgList[0]?.id || ''; //记住第一个信息ID
				//请求历史记录效果
				this.$request('/master/message/chatRecord', {
					...this.$params,
					page: this.current_page
				}).then(res => {
					res = res.data
					// 消息列表
					let list = res.data;
					list.forEach(item => {
						let msg = item.message
						if (msg.type == 'text') msg.content = this.replaceEmoji(msg.content)
					})
					this.msgList = res.current_page == 1 ? list : list.concat(this.msgList);
					//这段代码很重要，不然每次加载历史数据都会跳到顶部
					this.$nextTick(() => {
						if (e === 0) {
							this.scrollTop = 9999;
						} else {
							this.scrollToView = 'msg' + view_id;
						}
						this.$nextTick(() => {
							this.scrollAnimation = true; //恢复滚动动画
						});
					});
					// 判断尾页
					if (res.current_page == res.last_page) {
						// 下次不允许下拉加载数据了
						this.reload = true;
					} else {
						this.current_page = res.current_page + 1;
					}
					this.isHistoryLoading = false;
				}).catch(err => {
					this.isHistoryLoading = false;
				})
			},
			// 发送消息
			sendMsg(content, type) {
				let data = {
					...this.$params,
					type: 'chat',
					message: {
						type: type,
						content: content
					},
					createtime: parseInt(new Date().getTime() / 1000)
				};
				// 深拷贝移除数据绑定
				// this.onChat(JSON.parse(JSON.stringify(data)));
				// uni.$emit('onChat', data)
				// 发送消息
				this.$request('/master/message/sendChat', data).then(res => {
					this.onChat(res.data)
				})
			},
			onChat(msg) {
				switch (msg.message.type) {
					case 'text': //文字消息
						this.addTextMsg(msg);
						break;
					default:
						break;
				}
				// 滚动到底
				this.scrollBottom()
			},
			// 接受在线消息
			onSend(msg) {
				// if (msg.form.id == this.to_id) {
				this.onChat(msg)
				// }
			},
			scrollBottom() { // 滚动到底
				this.scrollToView = ''
				this.$nextTick(() => {
					setTimeout(() => {
						this.scrollToView = 'bottom'
					}, 20)
				});
			},
			// 添加文字消息到列表
			addTextMsg(msg) {
				msg.message.content = this.replaceEmoji(msg.message.content);
				this.msgList.push(msg);
			},
			// 表情数据
			emojiData() {
				var groups = {},
					categories = [],
					map = {};
				emotions.forEach(emotion => {
					var cate = emotion.category.length > 0 ? emotion.category : '默认';
					if (!groups[cate]) {
						groups[cate] = [];
						categories.push(cate);
					}
					groups[cate].push(emotion);
					map[emotion.phrase] = emotion.icon;
				});
				return {
					groups,
					categories,
					map
				};
			},
			//替换表情符号为图片
			replaceEmoji(str) {
				// 这里处理 链接   换行符
				let replacedStr = str.replace(/\[([^(\]|\[)]*)\]/g, (item, index) => {
					return '<img src="' + this.emojiList.map[item] + '" width="18rpx">';
				});
				return replacedStr.replace(/(\r\n)|(\n)/g, '<br>');
			},
			// 表情tab
			tabSelect(e) {
				this.TabCur = e.currentTarget.dataset.id;
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(content) {
				// 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
				let maxW = uni.upx2px(350); //350是定义消息图片最大宽度
				let maxH = uni.upx2px(350); //350是定义消息图片最大高度
				if (content.w > maxW || content.h > maxH) {
					let scale = content.w / content.h;
					content.w = scale > 1 ? maxW : maxH * scale;
					content.h = scale > 1 ? maxW / scale : maxH;
				}
				return content;
			},
			//更多功能(点击+弹出)
			showMore() {
				this.hideEmoji = true;
				if (this.hideMore) {
					this.hideMore = false;
					this.openDrawer();
				} else {
					this.hideDrawer();
				}
			},
			// 打开抽屉
			openDrawer() {
				this.emptybottom = true;
				this.popupLayerClass = true;
			},
			// 隐藏抽屉
			hideDrawer() {
				this.emptybottom = false;
				this.popupLayerClass = false;
				setTimeout(() => {
					this.hideMore = true;
					this.hideEmoji = true;
				}, 150);
			},
			// 选择表情
			chooseEmoji() {
				this.hideMore = true;
				if (this.hideEmoji) {
					this.hideEmoji = false;
					this.openDrawer();
				} else {
					this.hideDrawer();
				}
			},
			//添加表情
			addEmoji(em) {
				this.textMsg += em;
			},
			//获取焦点，如果不是选表情ing,则关闭抽屉
			textareaFocus() {
				this.emptybottom = true;
				if (this.popupLayerClass && this.hideMore == false) {
					this.hideDrawer();
				}
			},
			// 失去焦点
			textareaBlur() {
				this.emptybottom = false;
			},

			// 发送文字消息
			sendText() {
				this.hideDrawer(); //隐藏抽屉
				if (!this.textMsg) return
				let msg = this.textMsg
				this.sendMsg(msg, 'text');
				this.textMsg = ''; //清空输入框
			},
			// 关闭提示窗口
			discard() {
				return;
			}
		}
	};
</script>
<style>
	@import './chat/colorui.css';
	@import "./chat/wanlshop.css";
	@import './chat/iconfont.css';

	/* 1.0.2升级 */
	.cu-btn.sm {
		font-size: 26rpx;
	}

	.cu-modal {
		z-index: 2001;
	}

	.chatTips {
		display: inline-flex;
		align-items: center;
		position: absolute;
		z-index: 101;
		right: 0;
		left: 0;
		bottom: 120rpx;
		bottom: calc(120rpx + env(safe-area-inset-bottom));
	}

	.chatTips image {
		width: 100rpx;
		height: 100rpx;
		margin-right: 20rpx;
		flex-shrink: 0;
	}

	.chatTips .details {
		width: calc(100% - 100rpx - 20rpx);
	}

	.chatTips .details .title {
		width: 90%;
	}

	.cu-chat .cu-item>.main.goods .content,
	.cu-chat .cu-item>.main.order .content {
		display: block;
	}

	.cu-chat .cu-item>.main.order {
		max-width: calc(100% - 200rpx);
	}

	.cu-chat .cu-item>.main.order .product {
		background-color: #f9f9f9;
	}

	.cu-chat .cu-item>.main.order .product .item {
		display: flex;
		justify-content: space-between;
		margin-bottom: 25rpx;
	}

	.cu-chat .cu-item>.main.order .product .item:last-of-type {
		margin-bottom: 0;
	}

	.cu-chat .cu-item>.main.order .product .item .image,
	.product .item .image image {
		width: 100rpx;
		height: 100rpx;
		border-radius: 10rpx;
	}


	.cu-chat .cu-item>.main.order .product .item .details {
		display: flex;
		flex-wrap: wrap;
		width: calc(100% - 120rpx);
		align-content: space-between;
	}

	/* 1.0.2升级 模态框 */
	.wanl-modal .goods {
		display: flex;
		padding: 20rpx 0;
	}

	.wanl-modal .goods:last-of-type {
		padding-bottom: 0;
	}

	.wanl-modal .goods image {
		width: 180rpx;
		height: 180rpx;
		margin-right: 20rpx;
		flex-shrink: 0;
	}

	.wanl-modal .goods .details {
		flex-wrap: wrap;
		display: flex;
		flex: 1;
		align-content: space-between;
	}

	.wanl-modal .goods .details .info {
		width: 100%;
	}






	.opmenu {
		display: flex;
		flex-wrap: wrap;
		margin-top: 2rpx;
		color: #4c4c4c;
	}

	.opmenu .box {
		padding-top: 35rpx;
		padding-left: 50rpx;
		text-align: center;
	}

	.opmenu .box .icon {
		height: 120rpx;
		width: 120rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		justify-items: center;
		background-color: #ffffff;
		border-radius: 20rpx;
		font-size: 68rpx;
		margin-bottom: 10rpx;
	}

	.emptybottom {
		padding-bottom: 0 !important;
	}

	.hidden {
		display: none !important;
	}

	.cu-chat .cu-item>.main .content {
		font-size: 30rpx;
		border-radius: 17rpx;
	}

	.cu-chat .cu-item [class*='wlIcon-'] {
		font-size: 34rpx;
	}



	.popup-layer {
		transition: all 0.15s linear;
		width: 100%;
		height: 480rpx;
		background-color: #f5f5f5;
		position: fixed;
		z-index: 2000;
		top: 100%;
	}

	.popup-layer.showLayer {
		transform: translate3d(0, -480rpx, 0);
	}

	.popup-layer .emoji .emojinav {
		background-color: #f8f8f8;
	}

	.popup-layer .emoji .emojinav .item {
		display: flex;
		align-items: center;
		height: 100rpx;
		padding-left: 10rpx;
	}

	.popup-layer .emoji .emojinav .item .emojibg {
		background-color: #dedede;
	}

	.popup-layer .emoji .emojinav .item>view {
		margin: 0 25rpx;
		width: 60rpx;
		height: 60rpx;
		border-radius: 18rpx;
		background-repeat: no-repeat;
		background-size: 80%;
		background-position: center;
	}

	.popup-layer .emoji .subject {
		height: 380rpx;
		background-color: #f1f1f1;
	}

	.popup-layer .emoji .subject .item {
		padding: 25rpx;
	}

	.popup-layer .emoji .subject .item>view {
		background-repeat: no-repeat;
		background-size: 56%;
		background-position: center;
		width: 12.5%;
		height: 100rpx;
	}

	.input-box {
		width: 100%;
		min-height: 100rpx;
		padding-bottom: env(safe-area-inset-bottom);
		background-color: #f2f2f2;
		display: flex;
		align-items: flex-end;
		position: fixed;
		z-index: 2000;
		bottom: -2rpx;
		transition: all 0.15s linear;
	}

	.input-box [class*='wlIcon-'] {
		font-size: 50rpx;
		color: #323232;
	}

	.input-box .wlIcon-zhifeiji {
		color: #fe6600;
	}

	.input-box.showLayer {
		transform: translate3d(0, -480rpx, 0);
	}

	.input-box .voice,
	.input-box .more {
		flex-shrink: 0;
		width: 90rpx;
		height: 100rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.input-box .send {
		flex-shrink: 0;
		width: 90rpx;
		height: 100rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.input-box .send .btn {
		width: 110rpx;
		height: 70rpx;
		display: flex;
		justify-content: center;
		align-items: center;
		border-radius: 16rpx;
		font-size: 32rpx;
	}

	.input-box .textbox {
		width: 100%;
	}

	.input-box .textbox .voice-mode {
		width: calc(100% - 2upx);
		height: 80rpx;
		margin: 10rpx 0;
		border-radius: 16rpx;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 28rpx;
		background-color: #fff;
		color: #555;
	}

	.input-box .textbox .voice-mode.recording {
		background-color: #e5e5e5;
	}

	.input-box .textbox .text-mode {
		width: 100%;
		min-height: 80rpx;
		margin: 10rpx 0;
		display: flex;
		background-color: #ffffff;
		border-radius: 16rpx;
	}

	.input-box .textbox .text-mode .box {
		width: 100%;
		padding-left: 30rpx;
		min-height: 80rpx;
		display: flex;
		align-items: center;
	}

	.input-box .textbox .text-mode .box textarea {
		width: 100%;
	}

	.input-box .textbox .text-mode .em {
		flex-shrink: 0;
		width: 80rpx;
		padding-left: 10rpx;
		height: 80rpx;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.record {
		width: 39vw;
		height: 39vw;
		position: fixed;
		top: 35%;
		left: 30%;
		background-color: rgba(0, 0, 0, 0.8);
		border-radius: 40rpx;
	}

	.record .ing {
		width: 100%;
		height: 30vw;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	@keyframes volatility {
		0% {
			background-position: 0% 130%;
		}

		20% {
			background-position: 0% 150%;
		}

		30% {
			background-position: 0% 155%;
		}

		40% {
			background-position: 0% 160%;
		}

		50% {
			background-position: 0% 145%;
		}

		70% {
			background-position: 0% 150%;
		}

		80% {
			background-position: 0% 170%;
		}

		90% {
			background-position: 0% 160%;
		}

		100% {
			background-position: 0% 135%;
		}
	}

	.record .ing [class*='wlIcon'] {
		background-image: linear-gradient(to bottom, #ffffff, #565656 50%);
		background-size: 100% 200%;
		animation: volatility 1.5s ease-in-out -1.5s infinite alternate;
		-webkit-background-clip: text;
		-webkit-text-fill-color: transparent;
		font-size: 140rpx;
		padding-top: 40rpx;
		color: #f09b37;
	}

	.record .cancel {
		width: 100%;
		height: 30vw;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.record .cancel [class*='wlIcon'] {
		color: #fff;
		font-size: 150rpx;
	}

	.record .tis {
		width: 100%;
		height: 10vw;
		display: flex;
		justify-content: center;
		font-size: 24rpx;
		color: #fff;
	}

	.record .tis.change {
		color: #f09b37;
	}

	.content {
		width: 100%;
	}

	page {
		background-color: #ececec;
	}

	.content .msg-list,
	.cu-chat {
		position: absolute;
		top: 0;
		bottom: 100rpx;
		bottom: calc(env(safe-area-inset-bottom) + 100rpx);
		background-color: #ececec;
	}





	.loading {
		display: flex;
		justify-content: center;
	}

	@keyframes stretchdelay {

		0%,
		40%,
		100% {
			transform: scaleY(0.6);
		}

		20% {
			transform: scaleY(1);
		}
	}

	.loading .spinner {
		margin: 20upx 0;
		width: 60upx;
		height: 100upx;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	.loading .spinner view {
		background-color: #dadada;
		height: 50upx;
		width: 6upx;
		border-radius: 6upx;
		animation: stretchdelay 1.2s infinite ease-in-out;
	}

	.loading .spinner .rect2 {
		animation-delay: -1.1s;
	}

	.loading .spinner .rect3 {
		animation-delay: -1s;
	}

	.loading .spinner .rect4 {
		animation-delay: -0.9s;
	}

	.loading .spinner .rect5 {
		animation-delay: -0.8s;
	}



	.wanl-chat .chatfoot {
		position: fixed;
		width: 100%;
		bottom: 0;
		z-index: 1024;
	}

	.edgeInsetTop {
		height: var(--window-top);
	}
</style>
